package cn.im.qywx.service.impl;

import cn.im.qywx.dao.MeetingReserveDao;
import cn.im.qywx.dao.MeetingRoomDao;
import cn.im.qywx.model.MeetingReserve;
import cn.im.qywx.model.MeetingRoom;
import cn.im.qywx.queue.TokenQueue;
import cn.im.qywx.service.ImWxMeetingService;
import cn.im.qywx.system.SystemParams;
import cn.im.qywx.util.JsonUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@Slf4j
@Service
public class ImWxMeetingServiceImpl  implements ImWxMeetingService {

	@Autowired
	MeetingReserveDao meetingReserveDao;

	@Autowired
	MeetingRoomDao meetingRoomDao;

	@Autowired
	RestTemplate restTemplate;

	/** 获取会议室列表
	 */
	public List<MeetingRoom> getMeetingRoomList(){
		return  meetingRoomDao.getMeetingRoomByEnableOrderById(1);
	}


	public MeetingRoom getMeetingRoomById(long id){
		return meetingRoomDao.findByIdAndEnable(id,1);
	}

	public MeetingReserve getMeetingReserveById(long id){
		return meetingReserveDao.findByIdAndEnable(id,1);
	}
	
	/** 获取7天会议预定数据 并包含今日日期：{"toDay":"2018-08-30","datas":[]}
	 */
	public List<MeetingReserve> getWeekReserveList() {
		String today = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
		return  meetingReserveDao.findByMeetingDate(today);

	}

	/** 新增会议预定
	 */
	public Map<String,Object> addReserve(int roomId, String wxno,String userName, String date, int startTime, int endTime,String topic,String users) {
		if(StringUtils.isEmpty(wxno)){
			return returnNoLogin();
		}
		if(topic!=null && topic.length()>200){
			return returnResult("主题最多不能超过200个字符");
		}
		List<List<String>> lists_users = JsonUtils.json2list2String(users);
		if(lists_users==null){
			return returnResult("操作失败");
		}
		MeetingReserve reserve = new MeetingReserve();
		reserve.setRoomId(Long.valueOf(roomId));
		reserve.setWxno(wxno);
		reserve.setUserName(userName);
		reserve.setStartTime(startTime);
		reserve.setEndTime(endTime);
		reserve.setCreatTime(new Date());
		reserve.setTopic(topic);
		reserve.setUsers(users);
		try {
			reserve.setMeetingDate(new SimpleDateFormat("yyyy-MM-dd").parse(date));
		} catch (ParseException e) {
			e.printStackTrace();
		}
		
		Map<String, Object> result = saveReserve(reserve,date); 
		if("true".equals(result.get("result"))){
			sendMeetingTips(lists_users,reserve,getMeetingRoomById(reserve.getRoomId()));
		}
		return result;
	}
	/** 会议预定通知
	 */
	public void sendMeetingTips(final List<List<String>> users,final MeetingReserve reserve,final MeetingRoom room){
		addTipsUserNoRepeat(users,reserve.getWxno(),reserve.getUserName());
		//if(users.size()>0){
			new Thread(new Runnable(){
				public void run() {
					SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
					//生产文本消息
					StringBuilder content = new StringBuilder("会议预定");
					content.append("\n创建人: ").append(reserve.getUserName())
							.append("\n地点: ").append(room==null?"":room.getName())
							.append("\n时间: ").append(sdf.format(reserve.getMeetingDate())).append(" ")
							.append(toTimeStr(reserve.getStartTime())).append("~").append(toTimeStr(reserve.getEndTime()))
							.append("\n主题:\n　　　").append(reserve.getTopic()==null?"":reserve.getTopic().replace("\n", "\n　　　")).append("\n")
							.append("\n人员:\n");
					StringBuilder wxno = new StringBuilder();
					for(int i=0; i<users.size(); i++){
						List<String> l = users.get(i);
						wxno.append(l.get(0));
						content.append("　　　").append(l.get(1));
						if(i+1!=users.size()){
							wxno.append("|");
							content.append("\n");
						}
					}
					Map<String,Object> params = new HashMap<String,Object>();
					Map<String,String> text = new HashMap<String,String>();
					text.put("content", content.toString());
					params.put("touser", wxno.toString());
					params.put("msgtype", "text");
					params.put("agentid", SystemParams.AGENTID_MEETING);
					params.put("text", text);
					for(int i=0; i<3; i++){
						String url = SystemParams.URL_SEND+ TokenQueue.getToken(SystemParams.AGENTID_MEETING);
						String res = restTemplate.postForObject(url,JsonUtils.obj2json(params),String.class);
						log.info("result("+reserve.getId()+"):"+res);
						Map<String,Object> mapUser = JsonUtils.json2Map(res);
						if(mapUser!=null && ("0.0".equals(mapUser.get("errcode")+"") || "0".equals(mapUser.get("errcode")+"")))
							break;
						log.info("发送预定信息失败："+JsonUtils.obj2json(mapUser));
						try {Thread.sleep(15000);} catch (InterruptedException e) {}
					}
				}
			}).start();
		//}
	}
	
	/** 会议取消通知
	 */
	public void sendMeetingCancelTips(final MeetingReserve reserve,final MeetingRoom room){
		final List<List<String>> users = JsonUtils.json2list2String(reserve.getUsers());
		addTipsUserNoRepeat(users,reserve.getWxno(),reserve.getUserName());
		//if(users.size()>0){
			new Thread(new Runnable(){
				public void run() {
					SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
					//生产文本消息
					StringBuilder content = new StringBuilder("会议取消通知");
					content//.append("\n创建人: ").append(reserve.getUserName())
							.append("\n地点: ").append(room==null?"":room.getName())
							.append("\n时间: ").append(sdf.format(reserve.getMeetingDate())).append(" ")
							.append(toTimeStr(reserve.getStartTime())).append("~").append(toTimeStr(reserve.getEndTime()))
							.append("\n主题:\n　　　").append(reserve.getTopic()==null?"":reserve.getTopic().replace("\n", "\n　　　")).append("\n");
					StringBuilder wxno = new StringBuilder();
					for(int i=0; i<users.size(); i++){
						List<String> l = users.get(i);
						wxno.append(l.get(0));
						if(i+1!=users.size()){
							wxno.append("|");
						}
					}
					Map<String,Object> params = new HashMap<String,Object>();
					Map<String,String> text = new HashMap<String,String>();
					text.put("content", content.toString());
					params.put("touser", wxno.toString());
					params.put("msgtype", "text");
					params.put("agentid", SystemParams.AGENTID_MEETING);
					params.put("text", text);
					for(int i=0; i<3; i++){
						String res = restTemplate.postForObject(SystemParams.URL_SEND+TokenQueue.getToken(SystemParams.AGENTID_MEETING)
								,JsonUtils.obj2json(params),String.class);
						log.info("result("+reserve.getId()+"):"+res);
						Map<String,Object> mapUser = JsonUtils.json2Map(res);
						if(mapUser!=null && ("0.0".equals(mapUser.get("errcode")+"") || "0".equals(mapUser.get("errcode")+"")))
							break;
						log.info("发送会议取消信息失败："+JsonUtils.obj2json(mapUser));
						try {Thread.sleep(15000);} catch (InterruptedException e) {}
					}
				}
			}).start();
		//}
	}
	
	public void addTipsUserNoRepeat(List<List<String>> users,String wxno,String name){
		boolean have=false;
		for(List<String> user : users){
			if(wxno.equals(user.get(0))){
				have=true;
				break;
			}
		}
		if(!have){
			users.add(0,Arrays.asList(new String[]{wxno,name}));
		}
	}
	
	/** 保存会议预定，并检测是否有时间冲突
	 */
	private synchronized Map<String,Object> saveReserve(MeetingReserve reserve,String date){
		//返回结果
		Map<String,Object> result_param = new HashMap<String,Object>();

		//判断是否有时间冲突
		int result = meetingReserveDao.countExist(reserve.getRoomId(),date,reserve.getStartTime(),reserve.getEndTime());
		//有时间冲突,返回错误信息
		if(result > 0){
			result_param.put("result", "haveConf");
			result_param.put("reserveList",getWeekReserveList());
		}else{
			meetingReserveDao.save(reserve);
			result_param.put("result", "true");
			result_param.put("reserve", reserve);
		}
		return result_param;
	}
	
	/** 本人取消会议预定
	 */
	public Map<String,Object> cancelReserve(int id,String wxno){
		if(StringUtils.isEmpty(wxno)){
			return returnNoLogin();
		}
		Map<String,Object> result_param = new HashMap<String,Object>();
		result_param.put("id", id);
		result_param.put("wxno", wxno);
		MeetingReserve reserve = getMeetingReserveById(id);


		if(reserve!=null && meetingReserveDao.updateMeetingReserve(Long.valueOf(id),wxno) > 0){
			result_param.put("result", "true");
			sendMeetingCancelTips(reserve,getMeetingRoomById(reserve.getRoomId()));
		}else{
			result_param.put("result", "操作失败");
		}
		return result_param;
	}
	
	/** 本人取消会议预定
	 */
	public static Map<String,Object> returnNoLogin(){
		Map<String,Object> result = new HashMap<String,Object>();
		result.put("result", "失去了登陆信息，请重新进入本页面");
		return result;
	}
	/** 本人取消会议预定
	 */
	public static Map<String,Object> returnResult(String msg){
		Map<String,Object> result = new HashMap<String,Object>();
		result.put("result", msg);
		return result;
	}
	public static String toTimeStr(int time){
		String str = time+"";
		if(str.length()==3)
			return "0"+str.substring(0, 1)+":"+str.substring(1);
		else
			return str.substring(0, 2)+":"+str.substring(2);
	}

}
